package com.xc.controller;

import com.xc.SecurityUtil;
import com.xc.pojo.UserInfoBean;
import com.xc.util.AjaxResponse;
import com.xc.util.GlobalConfig;
import org.activiti.api.model.shared.model.VariableInstance;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 流程实例
 */
@RestController
@RequestMapping("/processInstance")
public class ProcessInstanceController {

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private ProcessRuntime processRuntime;
    @Autowired
    private SecurityUtil securityUtil;

    /**
     * 获取流程实例列表
     * @AuthenticationPrincipal 安全框架 security注解主认证用户实例，可以获取当前登录用户信息
     * @return
     */
    @GetMapping(value = "/getInstances")
    public AjaxResponse getInstances(@AuthenticationPrincipal UserInfoBean userInfoBean) {
        try{
            if (GlobalConfig.Test){// 是否开发阶段
                securityUtil.logInAs("bajie");
            }
            Page<ProcessInstance> processInstancePage = processRuntime.processInstances(Pageable.of(0, 10));
            List<ProcessInstance> list = processInstancePage.getContent();
            list.sort((y,x)->x.getStartDate().toString().compareTo(y.getStartDate().toString()));
            //list.sort(Comparator.comparing(ProcessInstance::getStartDate).reversed());
            List<HashMap<String, Object>> listMap = new ArrayList<HashMap<String, Object>>();
            for(ProcessInstance pi:list){
                HashMap<String, Object> hashMap = new HashMap<>();
                hashMap.put("id", pi.getId());
                hashMap.put("name", pi.getName());
                hashMap.put("status", pi.getStatus());
                hashMap.put("processDefinitionId", pi.getProcessDefinitionId());
                hashMap.put("processDefinitionKey", pi.getProcessDefinitionKey());
                hashMap.put("startDate", pi.getStartDate());
                hashMap.put("processDefinitionVersion", pi.getProcessDefinitionVersion());
                //因为processRuntime.processDefinition("流程部署ID")查询的结果没有部署流程与部署ID，所以用repositoryService查询
                // 根据流程实例里的 流程定义id 查询流程定义中的需要的数据
                ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
                        .processDefinitionId(pi.getProcessDefinitionId())
                        .singleResult();
                hashMap.put("resourceName", pd.getResourceName());
                hashMap.put("deploymentId", pd.getDeploymentId());
                listMap.add(hashMap);
            }
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(), listMap);
        }catch (Exception e){
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "获取流程实例失败", e.toString());
        }
    }

    /**
     * 启动流程实例
     * @param processDefinitionKey 流程定义key
     * @param instanceName 起一个流程实例名称
     * @return
     */
    @PostMapping(value = "/startProcess")
    public AjaxResponse startProcess(@RequestParam("processDefinitionKey") String processDefinitionKey, @RequestParam("instanceName") String instanceName) {
        try{
            if (GlobalConfig.Test){// 是否开发阶段
                securityUtil.logInAs("bajie");
            }else{
                // 获取登录账户名称
                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
            }
            ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder
                    .start()
                    .withProcessDefinitionKey(processDefinitionKey)
                    .withName(instanceName)
                    .withBusinessKey("业务key(通常为主键id)")
                    .build()
            );
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(), null);
        }catch (Exception e){
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "启动流程实例", e.toString());
        }
    }

    /**
     * 挂起流程实例
     * @param instanceId 流程实例id
     * @return
     */
    @PostMapping(value = "/suspendProcess")
    public AjaxResponse suspendProcess(@RequestParam("instanceId") String instanceId) {
        try{
            if (GlobalConfig.Test){// 是否开发阶段
                securityUtil.logInAs("bajie");
            }else{
                // 获取登录账户名称
                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
            }
            ProcessInstance processInstance = processRuntime.suspend(ProcessPayloadBuilder
                    .suspend()
                    .withProcessInstanceId(instanceId)
                    .build()
            );
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(), processInstance.getName());
        }catch (Exception e){
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "挂起流程实例失败", e.toString());
        }
    }

    /**
     * 激活流程实例
     * @param instanceId 流程实例id
     * @return
     */
    @PostMapping(value = "/resumeProcess")
    public AjaxResponse resumeProcess(@RequestParam("instanceId") String instanceId) {
        try{
            if (GlobalConfig.Test){// 是否开发阶段
                securityUtil.logInAs("bajie");
            }else{
                // 获取登录账户名称
                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
            }
            ProcessInstance processInstance = processRuntime.resume(ProcessPayloadBuilder
                    .resume()
                    .withProcessInstanceId(instanceId)
                    .build()
            );
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(), processInstance.getName());
        }catch (Exception e){
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "激活流程实例失败", e.toString());
        }
    }

    /**
     * 删除流程实例
     * @param instanceId 流程实例id
     * @return
     */
    @PostMapping(value = "/deleteProcess")
    public AjaxResponse deleteProcess(@RequestParam("instanceId") String instanceId) {
        try{
            if (GlobalConfig.Test){// 是否开发阶段
                securityUtil.logInAs("bajie");
            }else{
                // 获取登录账户名称
                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
            }
            ProcessInstance processInstance = processRuntime.delete(ProcessPayloadBuilder
                    .delete()
                    .withProcessInstanceId(instanceId)
                    .build()
            );
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(), processInstance.getName());
        }catch (Exception e){
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "删除流程实例失败", e.toString());
        }
    }

    /**
     * 查询流程实例参数
     * @param instanceId 流程实例id
     * @return
     */
    @PostMapping(value = "/variables")
    public AjaxResponse variables(@RequestParam("instanceId") String instanceId) {
        try{
            if (GlobalConfig.Test){// 是否开发阶段
                securityUtil.logInAs("bajie");
            }else{
                // 获取登录账户名称
                securityUtil.logInAs(SecurityContextHolder.getContext().getAuthentication().getName());
            }
            List<VariableInstance> variables = processRuntime.variables(ProcessPayloadBuilder
                    .variables()
                    .withProcessInstanceId(instanceId)
                    .build()
            );
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.SUCCESS.getCode(),
                    GlobalConfig.ResponseCode.SUCCESS.getDesc(), variables);
        }catch (Exception e){
            return AjaxResponse.AjaxData(GlobalConfig.ResponseCode.ERROR.getCode(),
                    "查询流程实例参数失败", e.toString());
        }
    }
}
